﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using ESpace;
using AMVInfoSpace;

namespace AMVNewsParser
{
    public partial class FormParse : Form
    {
        Dictionary<string, string> mHtml;

        public FormParse()
        {
            InitializeComponent();
            mHtml = GetMnemoHTML();
        }

        private void FormParse_Shown(object sender, EventArgs e)
        {
            AmvHtmlParser.fPathAkrossTagReplList = Application.StartupPath + "\\AkrossTagReplList.csv";
            Gl.infoL.Clear();
            ParseAMVNewsInfo();
            ParseAkrossInfo();
            ParseCreaConInfo();
            AmvHtmlParser.SaveAmvInfoList(Gl.fPathAmvInfo, Gl.infoL);

            Close();
        }

        void ParseAMVNewsInfo()
        {
            string[] fl = Directory.GetFiles(Gl.dPathHtmlDataAmvNews);
            progressBar1.Value = 0;
            progressBar1.Maximum = fl.Length;
            progressBar1.Visible = true;
            StringBuilder res = new StringBuilder();

            for (int f = 0; f < fl.Length; f++)
            {
                String STR = File.ReadAllText(fl[f], Encoding.UTF8);
                try
                {
                    int uin = Convert.ToInt32(new EFile(fl[f]).Name);
                    AMVInfoSpace.AMVInfo addAmv = AmvHtmlParser.ParseAMVNewsInfo(STR, uin);
                    Gl.infoL.Add(addAmv);
                    BuildParseLog(addAmv, res);
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }

                progressBar1.Value++;
                Text = new FileInfo(fl[f]).Name;

                Application.DoEvents();
            }

            Text = "Парсилка AMVNews";

            File.WriteAllText(Application.StartupPath + "\\AMVNewsInfo.txt", res.ToString(), Encoding.Unicode);
            progressBar1.Visible = false;
        }

        void ParseAkrossInfo()
        {
            string[] fl = Directory.GetFiles(Gl.dPathHtmlDataAkross);
            progressBar1.Value = 0;
            progressBar1.Maximum = fl.Length;
            progressBar1.Visible = true;
            StringBuilder res = new StringBuilder();

            for (int f = 0; f < fl.Length; f++)
            {
                String STR = File.ReadAllText(fl[f], Encoding.UTF8);
                try
                {
                    int uin = Convert.ToInt32(new EFile(fl[f]).Name);
                    AMVInfoSpace.AMVInfo addAmv = AmvHtmlParser.ParseAkrossInfo(STR, uin);
                    Gl.infoL.Add(addAmv);
                    BuildParseLog(addAmv, res);
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }

                progressBar1.Value++;
                Text = new FileInfo(fl[f]).Name;

                Application.DoEvents();
            }

            Text = "Парсилка AMVNews";

            File.WriteAllText(Application.StartupPath + "\\AkrossInfo.txt", res.ToString(), Encoding.Unicode);
            progressBar1.Visible = false;
        }

        void ParseCreaConInfo()
        {
            string[] fl = Directory.GetFiles(Gl.dPathHtmlDataCreaCon);
            progressBar1.Value = 0;
            progressBar1.Maximum = fl.Length;
            progressBar1.Visible = true;
            StringBuilder res = new StringBuilder();

            for (int f = 0; f < fl.Length; f++)
            {
                String STR = File.ReadAllText(fl[f], Encoding.UTF8);
                try
                {
                    int uin = Convert.ToInt32(new EFile(fl[f]).Name);
                    AMVInfoSpace.AMVInfo addAmv = AmvHtmlParser.ParseCreaConInfo(STR, uin);
                    Gl.infoL.Add(addAmv);
                    BuildParseLog(addAmv, res);
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }

                progressBar1.Value++;
                Text = new FileInfo(fl[f]).Name;

                Application.DoEvents();
            }

            Text = "Парсилка AMVNews";

            File.WriteAllText(Application.StartupPath + "\\CreaConInfo.txt", res.ToString(), Encoding.Unicode);
            progressBar1.Visible = false;
        }

        void BuildParseLog(AMVInfo AmvInfo, StringBuilder Sb)
        {
            Sb.AppendLine("UIN: " + AmvInfo.Number.ToString());
            Sb.AppendLine("НАЗВАНИЕ: " + AmvInfo.Name);
            Sb.AppendLine("ОЦЕНКА: " + AmvInfo.Rating.ToString());
            Sb.AppendLine("Дата создания: " + AmvInfo.CreateDate.ToString("dd.MM.yyyy HH.mm.ss"));
            Sb.AppendLine("Дата добавления: " + AmvInfo.AppenedDate.ToString("dd.MM.yyyy HH.mm.ss"));
            Sb.AppendLine("-------------");

            Sb.AppendLine("<ТЕГИ жанта>");
            foreach (string str in AmvInfo.TagGenre)
                Sb.AppendLine(str);
            Sb.AppendLine("<ТЕГИ прочие>");
            foreach (string str in AmvInfo.TagOther)
                Sb.AppendLine(str);
            Sb.AppendLine("-------------");

            Sb.AppendLine("<КОММЕНТАРИЙ>");
            Sb.AppendLine(AmvInfo.Comment);
            Sb.AppendLine("-------------");

            Sb.AppendLine("<АНИМЕ>");
            foreach (string str in AmvInfo.Anm)
                Sb.AppendLine(str);
            Sb.AppendLine("-------------");

            Sb.AppendLine("<МУЗЫКА>");
            foreach (string str in AmvInfo.Msc)
                Sb.AppendLine(str);
            Sb.AppendLine("-------------");

            Sb.AppendLine("<НАГРАДЫ>");
            foreach (string str in AmvInfo.Awd)
                Sb.AppendLine(str);
            Sb.AppendLine("-------------");

            Sb.AppendLine("<АВТОРЫ>");
            foreach (string str in AmvInfo.Atr)
                Sb.AppendLine(str);

            Sb.AppendLine("---------------------------------------------------------------------------------------------");

        }

        string GetNOTString(string str)
        {
            return "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r\n" +
                   "*****************************\r\n" +
                   str + "\r\n" +
                   "*****************************\r\n" +
                   "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r\n";
        }

        string GetRazdelAkross(string keyStr, ref string STR, out bool err)
        {
            int ind = STR.IndexOf(keyStr);
            string ret = "";
            if (ind != -1)
            {
                STR = STR.Substring(ind + keyStr.Length, STR.Length - (ind + keyStr.Length));
                List<int> ind1L = new List<int>();
                ind1L.Add(STR.IndexOf("</b>"));
                ind1L.Add(STR.IndexOf("</font>"));
                int ind1 = int.MaxValue;
                for (int i = 0; i < ind1L.Count; i++) if (ind1L[i] != -1 && ind1 > ind1L[i]) ind1 = ind1L[i];
                if (ind1 == int.MaxValue) { err = true; return ""; }
                string s = STR.Substring(0, ind1);
                //string[] sl = s.Split(':');
                //s = s.Substring(sl[0].Length + 1, s.Length - (sl[0].Length + 1)).Trim();
                ret = Gl.DelTags(s);
                if (ret == "--") ret = "";
                STR = STR.Substring(ind1, STR.Length - (ind1));
                err = ret == ""; // раздел найден, но он пуст
            }
            err = false;
            return ret;
        }

        string GetRazdelAMVNews(string keyStr, ref string STR, out bool err)
        {
            int ind = STR.IndexOf(keyStr);
            string ret = "";
            if (ind != -1)
            {
                STR = STR.Substring(ind + keyStr.Length, STR.Length - (ind + keyStr.Length));

                // нахождение позиции следующего тега
                List<int> ind1L = new List<int>();
                ind1L.Add(STR.IndexOf("</p>"));
                ind1L.Add(STR.IndexOf("</P>"));
                ind1L.Add(STR.IndexOf("<br>"));
                ind1L.Add(STR.IndexOf("<br />"));
                ind1L.Add(STR.IndexOf("<BR>"));
                ind1L.Add(STR.IndexOf("</div>"));
                ind1L.Add(STR.IndexOf("</STRONG>"));
                int ind1 = int.MaxValue;
                for (int i = 0; i < ind1L.Count; i++) if (ind1L[i] != -1 && ind1 > ind1L[i]) ind1 = ind1L[i];
                if (ind1 == int.MaxValue) { err = true; return ""; } // если следующий тег не найден, возвращаем ошибку

                // находим строку до следующего тега
                string s = STR.Substring(0, ind1);

                // находим окончания пред-тега
                string[] sl = s.Split(new char[1] { '>' }, 2);
                if (sl.Length == 1) { err = true; return ""; } // если окончание пред-тега не найдено, возвращаем ошибку
                s = s.Substring(sl[0].Length + 1, s.Length - (sl[0].Length + 1)).Trim(); // убираем пред-тег сперелди
                if (s[0] == ':') s = s.Substring(1, s.Length - 1); // убираем двоеточие спереди, если оно есть
                ret = Gl.DelTags(s);
                STR = STR.Substring(ind1, STR.Length - (ind1));
                err = ret == "";
            }
            err = false;
            return ret;
        }

        /*string ReplaceSpecSimbolsAMVNews(string s)
        {
            List<string[]> sl = new List<string[]>();

            sl.Add(new string[2] { "&#033;", "!" });
            sl.Add(new string[2] { "&#036;", "$" });
            sl.Add(new string[2] { "&#039;", "'" });
            sl.Add(new string[2] { "&#046;", "." });
            sl.Add(new string[2] { "&#062;", ">" });

            sl.Add(new string[2] { "&#33;", "!" });
            sl.Add(new string[2] { "&#36;", "$" });
            sl.Add(new string[2] { "&#46;", "." });
            sl.Add(new string[2] { "&#39;", "'" });
            sl.Add(new string[2] { "&#62;", ">" });
            sl.Add(new string[2] { "&#92;", "\\" });
            sl.Add(new string[2] { "&amp;", "&" });
            sl.Add(new string[2] { "&amp;", "&" });
            sl.Add(new string[2] { "&gt;", ">" });
            sl.Add(new string[2] { "&lt;", "<" });
            sl.Add(new string[2] { "&quot;", "\"" });
            sl.Add(new string[2] { "&nbsp;", " " });

            for (int i = 0; i < sl.Count; i++)
                s = s.Replace(sl[i][0], sl[i][1]).Replace(sl[i][0].ToUpper(), sl[i][1]);

            int IND = s.IndexOf("&#");
            while (IND != -1)
            {
                if (IND != -1)
                {
                    int IND1 = s.IndexOf(";", IND + 1);
                    string str = s.Substring(IND + 2, IND1 - IND - 2);

                    Int16 code;
                    if (Int16.TryParse(str, out code))
                    {
                        string str1 = ((char)code).ToString();
                        s = s.Replace("&#" + str + ";", str1);
                        //if (IND != -1) throw new Exception("не найден спец-символ '" + str1 + "' (" + str + ")");
                    }
                }

                IND = s.IndexOf("&#", IND + 2);
            }

            return s;
        }
*/

        Dictionary<string, string> GetMnemoHTML()
        {
            Dictionary<string, string> ret = new Dictionary<string, string>();

            ret.Add("&nbsp;", "");
            ret.Add("&iexcl;", "¡");
            ret.Add("&cent;", "¢");
            ret.Add("&pound;", "£");
            ret.Add("&curren;", "¤");
            ret.Add("&yen;", "¥");
            ret.Add("&brvbar;", "¦");
            ret.Add("&sect;", "§");
            ret.Add("&uml;", "¨");
            ret.Add("&copy;", "©");
            ret.Add("&ordf;", "ª");
            ret.Add("&laquo;", "«");
            ret.Add("&raquo;", "»");
            ret.Add("&not;", "¬");
            ret.Add("&shy;", "\r\n");
            ret.Add("&reg;", "®");
            ret.Add("&macr;", "¯");
            ret.Add("&deg;", "°");
            ret.Add("&plusmn;", "±");
            ret.Add("&sup2;", "²");
            ret.Add("&sup3;", "³");
            ret.Add("&acute;", "´");
            ret.Add("&micro;", "µ");
            ret.Add("&para;", "¶");
            ret.Add("&middot;", "·");
            ret.Add("&cedil;", "¸");
            ret.Add("&sup1;", "¹");
            ret.Add("&ordm;", "º");
            ret.Add("&frac14;", "¼");
            ret.Add("&frac12;", "½");
            ret.Add("&frac34;", "¾");
            ret.Add("&iquest;", "¿");
            // латинские с доп симполами
            ret.Add("&Agrave;", "À");
            ret.Add("&Aacute;", "Á");
            ret.Add("&Acirc;", "Â");
            ret.Add("&Atilde;", "Ã");
            ret.Add("&Auml;", "Ä");
            ret.Add("&Aring;", "Å");
            ret.Add("&AElig;", "Æ");
            ret.Add("&Ccedil;", "Ç");
            ret.Add("&Egrave;", "È");
            ret.Add("&Eacute;", "É");
            ret.Add("&Ecirc;", "Ê");
            ret.Add("&Euml;", "Ë");
            ret.Add("&Igrave;", "Ì");
            ret.Add("&Iacute;", "Í");
            ret.Add("&Icirc;", "Î");
            ret.Add("&Iuml;", "Ï");
            ret.Add("&ETH;", "Ð");
            ret.Add("&Ntilde;", "Ñ");
            ret.Add("&Ograve;", "Ò");
            ret.Add("&Oacute;", "Ó");
            ret.Add("&Ocirc;", "Ô");
            ret.Add("&Otilde;", "Õ");
            ret.Add("&Ouml;", "Ö");
            ret.Add("&times;", "×");
            ret.Add("&Oslash;", "Ø");
            ret.Add("&Ugrave;", "Ù");
            ret.Add("&Uacute;", "Ú");
            ret.Add("&Ucirc;", "Û");
            ret.Add("&Uuml;", "Ü");
            ret.Add("&Yacute;", "Ý");
            ret.Add("&THORN;", "Þ");
            ret.Add("&szlig;", "ß");
            ret.Add("&agrave;", "à");
            ret.Add("&aacute;", "á");
            ret.Add("&acirc;", "â");
            ret.Add("&atilde;", "ã");
            ret.Add("&auml;", "ä");
            ret.Add("&aring;", "å");
            ret.Add("&aelig;", "æ");
            ret.Add("&ccedil;", "ç");
            ret.Add("&egrave;", "è");
            ret.Add("&eacute;", "é");
            ret.Add("&ecirc;", "ê");
            ret.Add("&euml;", "ë");
            ret.Add("&igrave;", "ì");
            ret.Add("&iacute;", "í");
            ret.Add("&icirc;", "î");
            ret.Add("&iuml;", "ï");
            ret.Add("&eth;", "ð");
            ret.Add("&ntilde;", "ñ");
            ret.Add("&ograve;", "ò");
            ret.Add("&oacute;", "ó");
            ret.Add("&ocirc;", "ô");
            ret.Add("&otilde;", "õ");
            ret.Add("&ouml;", "ö");
            ret.Add("&divide;", "÷");
            ret.Add("&oslash;", "ø");
            ret.Add("&ugrave;", "ù");
            ret.Add("&uacute;", "ú");
            ret.Add("&ucirc;", "û");
            ret.Add("&uuml;", "ü");
            ret.Add("&yacute;", "ý");
            ret.Add("&thorn;", "þ");
            ret.Add("&yuml;", "ÿ");

            //Ссылки-мнемоники для символов, математических символов и греческих букв
            ret.Add("&fnof", "ƒ");
            ret.Add("&Alpha;", "Α");
            ret.Add("&Beta;", "Β");
            ret.Add("&Gamma;", "Γ");
            ret.Add("&Delta;", "Δ");
            ret.Add("&Epsilon;", "Ε");
            ret.Add("&Zeta;", "Ζ");
            ret.Add("&Eta;", "Η");
            ret.Add("&Theta;", "Θ");
            ret.Add("&Iota;", "Ι");
            ret.Add("&Kappa;", "Κ");
            ret.Add("&Lambda;", "Λ");
            ret.Add("&Mu;", "Μ");
            ret.Add("&Nu;", "Ν");
            ret.Add("&Xi;", "Ξ");
            ret.Add("&Omicron;", "Ο");
            ret.Add("&Pi;", "Π");
            ret.Add("&Rho;", "Ρ");
            ret.Add("&Sigma;", "Σ");
            ret.Add("&Tau;", "Τ");
            ret.Add("&Upsilon;", "Υ");
            ret.Add("&Phi;", "Φ");
            ret.Add("&Chi;", "Χ");
            ret.Add("&Psi;", "Ψ");
            ret.Add("&Omega;", "Ω");
            ret.Add("&alpha;", "α");
            ret.Add("&beta;", "β");
            ret.Add("&gamma;", "γ");
            ret.Add("&delta;", "δ");
            ret.Add("&epsilon;", "ε");
            ret.Add("&zeta;", "ζ");
            ret.Add("&eta;", "η");
            ret.Add("&theta;", "θ");
            ret.Add("&iota;", "ι");
            ret.Add("&kappa;", "κ");
            ret.Add("&lambda;", "λ");
            ret.Add("&mu;", "μ");
            ret.Add("&nu;", "ν");
            ret.Add("&xi;", "ξ");
            ret.Add("&omicron;", "ο");
            ret.Add("&pi;", "π");
            ret.Add("&rho;", "ρ");
            ret.Add("&sigmaf;", "ς");
            ret.Add("&sigma;", "σ");
            ret.Add("&tau;", "τ");
            ret.Add("&upsilon;", "υ");
            ret.Add("&phi;", "φ");
            ret.Add("&chi;", "χ");
            ret.Add("&psi;", "ψ");
            ret.Add("&omega;", "ω");
            ret.Add("&thetasy;", "ϑ");
            ret.Add("&upsih;", "ϒ");
            ret.Add("&piv;", "ϖ");
            //Основная пунктуация
            ret.Add("&bull;", "•");
            ret.Add("&hellip;", "…");
            ret.Add("&prime;", "′");
            ret.Add("&Prime;", "″");
            ret.Add("&oline;", "‾");
            ret.Add("&frasl;", "⁄");
            //Буквоподобные символы
            ret.Add("&weierp;", "℘");
            ret.Add("&image;", "ℑ");
            ret.Add("&real;", "ℜ");
            ret.Add("&trade;", "™");
            ret.Add("&alefsym;", "ℵ");
            //Стрелки
            ret.Add("&larr;", "←");
            ret.Add("&uarr;", "↑");
            ret.Add("&rarr;", "→");
            ret.Add("&darr;", "↓");
            ret.Add("&harr;", "↔");
            ret.Add("&crarr;", "↵");
            ret.Add("&lArr;", "⇐");
            ret.Add("&uArr;", "⇑");
            ret.Add("&rArr;", "⇒");
            ret.Add("&dArr;", "⇓");
            ret.Add("&hArr;", "⇔");
            //Математические операции
            ret.Add("&forall;", "∀");
            ret.Add("&part;", "∂");
            ret.Add("&exist;", "∃");
            ret.Add("&empty;", "∅");
            ret.Add("&nabla;", "∇");
            ret.Add("&isin;", "∈");
            ret.Add("&notin;", "∉");
            ret.Add("&ni;", "∋");
            ret.Add("&prod;", "∏");
            ret.Add("&sum;", "∑");
            ret.Add("&minus;", "−");
            ret.Add("&lowast;", "∗");
            ret.Add("&radic;", "√");
            ret.Add("&prop;", "∝");
            ret.Add("&infin;", "∞");
            ret.Add("&ang;", "∠");
            ret.Add("&and;", "∧");
            ret.Add("&or;", "∨");
            ret.Add("&cap;", "∩");
            ret.Add("&cup;", "∪");
            ret.Add("&int;", "∫");
            ret.Add("&there4;", "∴");
            ret.Add("&sim;", "∼");
            ret.Add("&cong;", "≅");
            ret.Add("&asymp;", "≈");
            ret.Add("&ne;", "≠");
            ret.Add("&equiv;", "≡");
            ret.Add("&le;", "≤");
            ret.Add("&ge;", "≥");
            ret.Add("&sub;", "⊂");
            ret.Add("&sup;", "⊃");
            ret.Add("&nsub;", "⊄");
            ret.Add("&sube;", "⊆");
            ret.Add("&supe;", "⊇");
            ret.Add("&oplus;", "⊕");
            ret.Add("&otimes;", "⊗");
            ret.Add("&perp;", "⊥");
            ret.Add("&sdot;", "⋅");
            //Различные Технические
            ret.Add("&lceil;", "⌈");
            ret.Add("&rceil;", "⌉");
            ret.Add("&lfloor;", "⌊");
            ret.Add("&rfloor;", "⌋");
            ret.Add("&lang;", "〈");
            ret.Add("&rang;", "〉");
            //Геометрические Фигуры
            ret.Add("&loz;", "◊");
            //Различные Символы
            ret.Add("&spades;", "♠");
            ret.Add("&clubs;", "♣");
            ret.Add("&hearts;", "♥");
            ret.Add("&diams;", "♦");

            //Ссылки-мнемоники для символов разметки и интернационализации

            //C0 Controls and Basic Latin
            ret.Add("&apos;", "'");
            ret.Add("&quot;", "\"");
            ret.Add("&amp;", "&");
            ret.Add("&lt;", "<");
            ret.Add("&gt;", ">");
            //Latin Extended-A
            ret.Add("&OElig;", "Œ");
            ret.Add("&oelig;", "œ");
            ret.Add("&Scaron;", "Š");
            ret.Add("&scaron;", "š");
            ret.Add("&Yuml;", "Ÿ");
            //Модификаторы букв
            ret.Add("&circ;", "ˆ");
            ret.Add("&tilde;", "˜");
            //Общая Пунктуация
            ret.Add("&ensp;", " ");
            ret.Add("&emsp;", " ");
            ret.Add("&thinsp;", " ");
            ret.Add("&zwnj;", "");
            ret.Add("&zwj;", "");
            ret.Add("&lrm;", "");
            ret.Add("&rlm;", "");
            ret.Add("&ndash;", "–");
            ret.Add("&mdash;", "—");
            ret.Add("&lsquo;", "‘");
            ret.Add("&rsquo;", "’");
            ret.Add("&sbquo;", "‚");
            ret.Add("&ldquo;", "“");
            ret.Add("&rdquo;", "”");
            ret.Add("&bdquo;", "„");
            ret.Add("&dagger;", "†");
            ret.Add("&Dagger;", "‡");
            ret.Add("&permil;", "‰");
            ret.Add("&lsaquo;", "‹");
            ret.Add("&rsaquo;", "›");
            ret.Add("&euro;", "€");

            return ret;
        }

        string ReplaceSpecSimbols(string s)
        {
            foreach (KeyValuePair<string, string> val in mHtml)
                if (s.Contains(val.Key)) s = s.Replace(val.Key, val.Value);

            int IND = s.IndexOf("&#");
            while (IND != -1)
            {
                if (IND != -1)
                {
                    int IND1 = s.IndexOf(";", IND + 1);
                    string str = s.Substring(IND + 2, IND1 - IND - 2);

                    Int16 code;
                    if (Int16.TryParse(str, out code))
                    {
                        string str1 = ((char)code).ToString();
                        s = s.Replace("&#" + str + ";", str1);
                        //if (IND != -1) throw new Exception("не найден спец-символ '" + str1 + "' (" + str + ")");
                    }
                }

                IND = s.IndexOf("&#", IND + 2);
            }

            return s;
        }

    }
}
